#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <string.h>
#include <linux/input.h>
#include <termios.h> //配置串口的头文件
#include <stdint.h> // 新增：用于明确数据类型
#include <pthread.h> // 新增：多线程支持

#define UART_PATH "/dev/ttySAC1"
#define TOUCH_PATH "/dev/input/event0"
#define LCD_PATH "/dev/fb0"
#define PWM_PATH "/dev/pwm"

#define INT_MIN -2147483648
#define INT_MAX 2147483647
#define DECIMAL_PRECISION 1 // 保留1位小数（如温度25.3℃）

#define GY39_BAUD_RATE B9600 // 明确波特率
#define LIGHT_FRAME_HEADER "\x5A\x5A\x15" // 光照数据帧头：5A 5A 15
#define ENV_FRAME_HEADER "\x5A\x5A\x45" // 环境数据帧头：5A 5A 45
#define LCD_WIDTH 800 // 定义LCD宽度
#define LCD_HEIGHT 480 // 定义LCD高度

// 显示数据函数声明
int showdata_in_lcd(void); 
void display_number_with_decimal(int x0, int y0, int num);
int show_bmp(char * filename,int x0,int y0);
int lcd_draw_clear(int x0,int y0,int w,int h,int color);
void display_number(int x0, int y0, int num);
void lcd_close(void);
int lcd_init(void);
int GY39(void);
int uart_init(const char *uart_name);
int get_digits(int num, int* digits);
int count_digits(int num);
void display_decimal_point(int x0, int y0);
void display_char(int x0,int y0,int w,int h,unsigned char name[]);
void LCD_draw_point(int x, int y, int color);
void split_decimal(int num, int* integer_part, int* decimal_part);
int beep_control(int beep_status);
int get_user_input(int *x, int *y);
void* handle_touch_event(void* arg);
int led_flow_control(int led_status);
void* gy39_thread(void* arg);
void* led_thread(void* arg);
void* beep_thread(void* arg);
int set_Temperature_alarmnumber(int temp);
int set_Lux_alarmnumber(int lux);
int print_warning_sign(int x,int y);
void display_char_warning(int x0,int y0,int w,int h,unsigned char name[]);


volatile int T = 0; // 温度
volatile int P = 0; // 气压
volatile int H = 0; // 湿度
volatile int A = 0; // 海拔
volatile int L = 0; // 光照
volatile int T_alarm = 0;//温度阈值
volatile int L_alarm = 0;//光照阈值

// 互斥锁（用于保护共享资源）
pthread_mutex_t hardware_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t sensor_mutex = PTHREAD_MUTEX_INITIALIZER;

volatile int stop_beep = 0;
pthread_t touch_thread;

//警示图案
/*--  文字:  ！  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=48x48   --*/
unsigned char warning_sign[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x0F,0xC0,0x00,0x00,0x00,0x00,0x1F,0xC0,0x00,
    0x00,0x00,0x00,0x1F,0xC0,0x00,0x00,0x00,0x00,0x1F,0xC0,0x00,0x00,0x00,0x00,0x0F,
    0xC0,0x00,0x00,0x00,0x00,0x0F,0xC0,0x00,0x00,0x00,0x00,0x0F,0xC0,0x00,0x00,0x00,
    0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x0F,0x80,0x00,
    0x00,0x00,0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x0F,
    0x80,0x00,0x00,0x00,0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x07,0x80,0x00,0x00,0x00,
    0x00,0x07,0x80,0x00,0x00,0x00,0x00,0x07,0x80,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
    0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x03,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x1F,0xC0,0x00,
    0x00,0x00,0x00,0x1F,0xE0,0x00,0x00,0x00,0x00,0x1F,0xE0,0x00,0x00,0x00,0x00,0x1F,
    0xC0,0x00,0x00,0x00,0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

/*--  文字:  百  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=48x48   --*/
unsigned char baichar[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x01,0xE0,0x0F,0xFF,
    0xFF,0xFF,0xFF,0xF0,0x1F,0xFF,0xFF,0xFF,0xFF,0xF8,0x0F,0x00,0x07,0x80,0x00,0x00,
    0x00,0x00,0x07,0xE0,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x00,0x00,0x0F,0x80,
    0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,
    0x0E,0x00,0x00,0x00,0x00,0x30,0x1C,0x00,0x38,0x00,0x00,0x3F,0xFF,0xFF,0xFC,0x00,
    0x00,0x3F,0xFF,0xFF,0xFE,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,
    0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,
    0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,
    0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3F,0xFF,0xFF,
    0xFC,0x00,0x00,0x3F,0xFF,0xFF,0xFC,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,
    0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,
    0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,
    0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,
    0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3F,0xFF,0xFF,0xFC,0x00,
    0x00,0x3F,0xFF,0xFF,0xFC,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x3E,0x00,0x00,
    0x7C,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // 用于存储字符的数组

/*--  文字:  帕  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=48x48   --*/
unsigned char pachar[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x01,
    0xC0,0x00,0x00,0x1F,0x00,0x01,0xE0,0x00,0x00,0x1E,0x00,0x01,0xF0,0x00,0x00,0x1E,
    0x00,0x03,0xE0,0x00,0x00,0x1E,0x00,0x03,0xC0,0x00,0x00,0x1E,0x00,0x03,0xC0,0x00,
    0x00,0x1E,0x00,0x03,0x80,0x00,0x00,0x1E,0x00,0x07,0x80,0x00,0x0C,0x1E,0x39,0x87,
    0x00,0xE0,0x0F,0xFF,0xFD,0xFF,0xFF,0xF0,0x0F,0xFF,0xFD,0xFF,0xFF,0xF8,0x0F,0x1E,
    0x79,0xE0,0x00,0xF0,0x0F,0x1E,0x79,0xE0,0x00,0xF0,0x0F,0x1E,0x79,0xE0,0x00,0xF0,
    0x0F,0x1E,0x79,0xE0,0x00,0xF0,0x0F,0x1E,0x79,0xE0,0x00,0xF0,0x0F,0x1E,0x79,0xE0,
    0x00,0xF0,0x0F,0x1E,0x79,0xE0,0x00,0xF0,0x0F,0x1E,0x79,0xE0,0x00,0xF0,0x0F,0x1E,
    0x79,0xE0,0x00,0xF0,0x0F,0x1E,0x79,0xE0,0x00,0xF0,0x0F,0x1E,0x79,0xE0,0x00,0xF0,
    0x0F,0x1E,0x79,0xFF,0xFF,0xF0,0x0F,0x1E,0x79,0xFF,0xFF,0xF0,0x0F,0x1E,0x79,0xE0,
    0x00,0xF0,0x0F,0x1E,0x79,0xE0,0x00,0xF0,0x0F,0x1E,0x79,0xE0,0x00,0xF0,0x0F,0x1E,
    0x79,0xE0,0x00,0xF0,0x0F,0x1F,0x79,0xE0,0x00,0xF0,0x0F,0x1F,0xF9,0xE0,0x00,0xF0,
    0x0F,0x1F,0xF9,0xE0,0x00,0xF0,0x0F,0x1E,0xF1,0xE0,0x00,0xF0,0x0E,0x1E,0x41,0xE0,
    0x00,0xF0,0x00,0x1E,0x01,0xE0,0x00,0xF0,0x00,0x1E,0x01,0xE0,0x00,0xF0,0x00,0x1E,
    0x01,0xE0,0x00,0xF0,0x00,0x1E,0x01,0xFF,0xFF,0xF0,0x00,0x1E,0x01,0xFF,0xFF,0xF0,
    0x00,0x1E,0x01,0xE0,0x00,0xF0,0x00,0x1E,0x01,0xE0,0x00,0xF0,0x00,0x1E,0x01,0xE0,
    0x00,0xF0,0x00,0x1E,0x01,0xE0,0x00,0xF0,0x00,0x1E,0x01,0xC0,0x00,0xE0,0x00,0x18,
    0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
/*--  文字:  米  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=48x48   --*/
unsigned char meterchar[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,
    0x00,0x00,0x00,0x00,0x07,0xE0,0x00,0x00,0x00,0x00,0x03,0xF0,0x18,0x00,0x00,0x00,
    0x03,0xC0,0x3C,0x00,0x00,0xE0,0x03,0xC0,0x3E,0x00,0x00,0x70,0x03,0xC0,0x3F,0x00,
    0x00,0x7C,0x03,0xC0,0x7E,0x00,0x00,0x3E,0x03,0xC0,0x7C,0x00,0x00,0x1F,0x03,0xC0,
    0xF8,0x00,0x00,0x1F,0x83,0xC1,0xF0,0x00,0x00,0x0F,0x83,0xC1,0xE0,0x00,0x00,0x0F,
    0x83,0xC3,0xC0,0x00,0x00,0x0F,0x83,0xC3,0x80,0x00,0x00,0x07,0x83,0xC7,0x80,0x00,
    0x00,0x07,0x03,0xCF,0x00,0xE0,0x00,0x00,0x03,0xDE,0x01,0xF0,0x1F,0xFF,0xFF,0xFF,
    0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xFF,0xFC,0x0E,0x00,0x1F,0xF0,0x00,0x00,0x00,0x00,
    0x1F,0xF0,0x00,0x00,0x00,0x00,0x3F,0xF8,0x00,0x00,0x00,0x00,0x3F,0xF8,0x00,0x00,
    0x00,0x00,0x7F,0xDC,0x00,0x00,0x00,0x00,0xFB,0xDE,0x00,0x00,0x00,0x00,0xF3,0xCE,
    0x00,0x00,0x00,0x01,0xF3,0xCF,0x00,0x00,0x00,0x03,0xE3,0xC7,0x80,0x00,0x00,0x07,
    0xC3,0xC3,0xC0,0x00,0x00,0x07,0x83,0xC3,0xE0,0x00,0x00,0x0F,0x03,0xC1,0xF0,0x00,
    0x00,0x1F,0x03,0xC0,0xFC,0x00,0x00,0x3E,0x03,0xC0,0x7E,0x00,0x00,0x7C,0x03,0xC0,
    0x3F,0x80,0x00,0xF0,0x03,0xC0,0x3F,0xC0,0x01,0xE0,0x03,0xC0,0x1F,0xF8,0x03,0xC0,
    0x03,0xC0,0x07,0xFE,0x07,0x80,0x03,0xC0,0x03,0xFC,0x1E,0x00,0x07,0xC0,0x01,0xE0,
    0x3C,0x00,0x07,0xC0,0x00,0xC0,0x70,0x00,0x07,0xC0,0x00,0x00,0x00,0x00,0x07,0xC0,
    0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x00,0x00,
    0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // 指向帧缓冲的指针

/*--  文字:  %  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=24x48   --*/
unsigned char percentchar[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x70,0x3F,0x80,0xE0,0x79,0xC0,
    0xE0,0x71,0xE1,0xC0,0xF1,0xE1,0xC0,0xF1,0xE1,0xC0,0xF1,0xE3,0x80,0xF1,0xE3,0x80,
    0xF1,0xE7,0x00,0xF1,0xE7,0x00,0xF1,0xE7,0x00,0xF1,0xEE,0x00,0xF1,0xEE,0x00,0x71,
    0xFC,0x00,0x79,0xDC,0x00,0x3F,0xD8,0x60,0x3F,0xB9,0xF8,0x06,0x3B,0xFC,0x00,0x77,
    0x9C,0x00,0x77,0x1E,0x00,0xEF,0x1E,0x00,0xEF,0x0E,0x00,0xEF,0x0F,0x01,0xCF,0x0F,
    0x01,0xCF,0x0F,0x03,0x8F,0x0F,0x03,0x8F,0x0F,0x03,0x0F,0x0E,0x07,0x07,0x1E,0x07,
    0x07,0x1E,0x0E,0x07,0x9C,0x0E,0x03,0xFC,0x0C,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 


/*--  文字:  0  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=24x48   --*/
unsigned char zero[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x01,0xFF,0x80,0x03,0xC3,
    0xC0,0x07,0x81,0xE0,0x0F,0x81,0xF0,0x0F,0x00,0xF0,0x1F,0x00,0xF8,0x1F,0x00,0xF8,
    0x1E,0x00,0x78,0x3E,0x00,0x7C,0x3E,0x00,0x7C,0x3E,0x00,0x7C,0x3E,0x00,0x7C,0x3E,
    0x00,0x7C,0x3E,0x00,0x7C,0x3E,0x00,0x7C,0x3E,0x00,0x7C,0x3E,0x00,0x7C,0x3E,0x00,
    0x7C,0x3E,0x00,0x7C,0x3E,0x00,0x7C,0x3E,0x00,0x7C,0x3E,0x00,0x7C,0x3E,0x00,0x7C,
    0x3E,0x00,0x78,0x1F,0x00,0xF8,0x1F,0x00,0xF8,0x0F,0x00,0xF0,0x0F,0x81,0xF0,0x07,
    0x81,0xE0,0x03,0xC3,0xC0,0x01,0xFF,0x80,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
/*--  文字:  1  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=24x48   --*/
unsigned char one[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x1C,0x00,0x00,0x7C,
    0x00,0x07,0xFC,0x00,0x07,0xFC,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,
    0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,
    0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,
    0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,
    0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,
    0x3E,0x00,0x00,0x3E,0x00,0x07,0xFF,0xE0,0x07,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

/*--  文字:  2  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=24x48   --*/
unsigned char two[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x80,0x03,0xFF,0xC0,0x0F,0x83,
    0xE0,0x0E,0x01,0xF0,0x1E,0x00,0xF8,0x1E,0x00,0xF8,0x3E,0x00,0x78,0x3E,0x00,0x78,
    0x3F,0x00,0x78,0x3F,0x00,0x78,0x1F,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0xF0,0x00,
    0x01,0xF0,0x00,0x01,0xE0,0x00,0x03,0xC0,0x00,0x07,0xC0,0x00,0x0F,0x80,0x00,0x0F,
    0x00,0x00,0x1E,0x00,0x00,0x3C,0x00,0x00,0x78,0x00,0x00,0xF0,0x00,0x01,0xE0,0x00,
    0x03,0xC0,0x00,0x07,0x80,0x1C,0x0F,0x00,0x1C,0x0E,0x00,0x38,0x1C,0x00,0x38,0x3C,
    0x00,0x78,0x3F,0xFF,0xF8,0x3F,0xFF,0xF8,0x3F,0xFF,0xF8,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    

/*--  文字:  3  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=24x48   --*/
unsigned char three[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x00,0x07,0xFF,0x80,0x0F,0x07,
    0xC0,0x1E,0x03,0xE0,0x1E,0x01,0xF0,0x1E,0x01,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0xF0,
    0x1E,0x00,0xF0,0x00,0x00,0xF0,0x00,0x01,0xF0,0x00,0x01,0xF0,0x00,0x01,0xE0,0x00,
    0x07,0xC0,0x00,0x1F,0x80,0x00,0xFE,0x00,0x00,0x7F,0x80,0x00,0x03,0xE0,0x00,0x01,
    0xF0,0x00,0x00,0xF0,0x00,0x00,0xF8,0x00,0x00,0x78,0x00,0x00,0x7C,0x00,0x00,0x7C,
    0x1E,0x00,0x7C,0x3F,0x00,0x7C,0x3F,0x00,0x78,0x3F,0x00,0xF8,0x3E,0x00,0xF8,0x1E,
    0x01,0xF0,0x0F,0x03,0xE0,0x07,0xFF,0xC0,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

/*--  文字:  4  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=24x48   --*/    
unsigned char four[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x00,0x03,0xC0,0x00,0x07,
    0xC0,0x00,0x0F,0xC0,0x00,0x0F,0xC0,0x00,0x1F,0xC0,0x00,0x1F,0xC0,0x00,0x3F,0xC0,
    0x00,0x77,0xC0,0x00,0x77,0xC0,0x00,0xE7,0xC0,0x01,0xE7,0xC0,0x01,0xC7,0xC0,0x03,
    0x87,0xC0,0x03,0x87,0xC0,0x07,0x07,0xC0,0x0E,0x07,0xC0,0x0E,0x07,0xC0,0x1C,0x07,
    0xC0,0x3C,0x07,0xC0,0x38,0x07,0xC0,0x7F,0xFF,0xFC,0x7F,0xFF,0xFE,0x3F,0xFF,0xFC,
    0x00,0x07,0xC0,0x00,0x07,0xC0,0x00,0x07,0xC0,0x00,0x07,0xC0,0x00,0x07,0xC0,0x00,
    0x07,0xC0,0x00,0x07,0xC0,0x00,0x7F,0xFC,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

/*--  文字:  5  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=24x48   --*/     
unsigned char five[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0xF8,0x0F,0xFF,0xF8,0x0F,0xFF,
    0xF8,0x0E,0x00,0x00,0x0E,0x00,0x00,0x0E,0x00,0x00,0x0E,0x00,0x00,0x0E,0x00,0x00,
    0x0E,0x00,0x00,0x0E,0x00,0x00,0x0E,0x00,0x00,0x0E,0x3E,0x00,0x0F,0xFF,0xC0,0x0F,
    0xFF,0xE0,0x0F,0x83,0xF0,0x1F,0x01,0xF0,0x1E,0x00,0xF8,0x0C,0x00,0xF8,0x00,0x00,
    0x78,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x7C,0x1E,0x00,0x7C,
    0x3F,0x00,0x7C,0x3F,0x00,0x78,0x3F,0x00,0x78,0x3E,0x00,0xF8,0x1E,0x00,0xF0,0x1E,
    0x01,0xF0,0x0F,0x03,0xE0,0x07,0xFF,0xC0,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

/*--  文字:  6  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=24x48   --*/     
unsigned char six[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0xFF,0xE0,0x03,0xE1,
    0xF0,0x03,0xC1,0xF8,0x07,0x81,0xF8,0x0F,0x01,0xF0,0x0F,0x00,0xE0,0x1E,0x00,0x00,
    0x1E,0x00,0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x3E,0x3F,0x80,0x3E,
    0xFF,0xE0,0x3F,0xF3,0xF0,0x3F,0xC1,0xF8,0x3F,0x80,0xF8,0x3F,0x00,0x7C,0x3E,0x00,
    0x7C,0x3E,0x00,0x7C,0x3E,0x00,0x3C,0x3E,0x00,0x3C,0x3E,0x00,0x3C,0x3E,0x00,0x3C,
    0x3E,0x00,0x3C,0x3E,0x00,0x7C,0x1F,0x00,0x7C,0x1F,0x00,0x78,0x0F,0x80,0x78,0x0F,
    0x80,0xF0,0x07,0xE1,0xE0,0x03,0xFF,0xC0,0x00,0xFF,0x80,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

/*--  文字:  7  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=24x48   --*/
unsigned char seven[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xFF,0xFC,0x1F,0xFF,0xFC,0x1F,0xFF,
    0xF8,0x1F,0x00,0x78,0x1C,0x00,0x70,0x1C,0x00,0xF0,0x38,0x00,0xE0,0x38,0x01,0xE0,
    0x00,0x01,0xC0,0x00,0x03,0xC0,0x00,0x03,0x80,0x00,0x07,0x80,0x00,0x07,0x00,0x00,
    0x0F,0x00,0x00,0x0E,0x00,0x00,0x1E,0x00,0x00,0x1E,0x00,0x00,0x1C,0x00,0x00,0x3C,
    0x00,0x00,0x3C,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x78,0x00,0x00,0x78,0x00,
    0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0xFC,0x00,0x00,0xFC,0x00,0x00,
    0xFC,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

/*--  文字:  8  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=24x48   --*/
unsigned char eight[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x80,0x07,0xFF,0xC0,0x0F,0x81,
    0xE0,0x1F,0x00,0xF0,0x1E,0x00,0x78,0x3C,0x00,0x78,0x3C,0x00,0x78,0x3C,0x00,0x7C,
    0x3C,0x00,0x7C,0x3E,0x00,0x78,0x1F,0x00,0x78,0x1F,0x80,0x70,0x0F,0xC0,0xF0,0x07,
    0xF1,0xE0,0x03,0xFF,0xC0,0x01,0xFF,0x00,0x03,0xFF,0xC0,0x07,0x9F,0xE0,0x0F,0x07,
    0xF0,0x1E,0x03,0xF0,0x3C,0x01,0xF8,0x3C,0x00,0xF8,0x3C,0x00,0x7C,0x7C,0x00,0x7C,
    0x78,0x00,0x3C,0x78,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x78,0x3C,0x00,0x78,0x1E,
    0x00,0xF0,0x0F,0x81,0xE0,0x07,0xFF,0xC0,0x01,0xFF,0x80,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

/*--  文字:  9  --*/
/*--  宋体36;  此字体下对应的点阵为：宽x高=24x48   --*/
unsigned char nine[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x00,0x07,0xFF,0x80,0x0F,0x83,
    0xC0,0x1F,0x01,0xE0,0x1E,0x00,0xF0,0x3E,0x00,0xF0,0x3C,0x00,0x78,0x3C,0x00,0x78,
    0x7C,0x00,0x78,0x7C,0x00,0x7C,0x7C,0x00,0x7C,0x7C,0x00,0x7C,0x7C,0x00,0x7C,0x3C,
    0x00,0x7C,0x3E,0x00,0xFC,0x3E,0x00,0xFC,0x3E,0x01,0xFC,0x1F,0x07,0xFC,0x0F,0xFF,
    0x7C,0x07,0xFE,0x7C,0x01,0xF8,0x7C,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0xF8,
    0x00,0x00,0xF8,0x00,0x00,0xF0,0x0E,0x01,0xF0,0x1F,0x01,0xE0,0x1F,0x03,0xE0,0x1F,
    0x07,0xC0,0x1F,0x8F,0x80,0x0F,0xFF,0x00,0x03,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};


// 数字字符点阵数组指针
unsigned char* numdz[] = {zero, one, two, three, four, five, six, seven, eight, nine};

int* plcd = NULL; // 全局变量，用于存储LCD映射的内存地址;
int lcd_fd = -1;  // 全局变量，用于存储LCD文件描述符;
int beep_fd = -1; //蜂鸣器文件描述符
int touch_fd = -1; //触摸文件描述符
int led_fd = -1; //LED文件描述符

// 共享状态变量（使用volatile确保编译器不优化）
volatile int system_running = 1; // 系统运行标志
volatile int alarm_triggered = 0; // 报警触发标志


//定义led灯开关状态
static char d7_on [2]={1,7};
static char d8_on [2]={1,8};
static char d9_on [2]={1,9};
static char d10_on [2]={1,10};
static char d7_off[2]={0,7};
static char d8_off[2]={0,8};
static char d9_off[2]={0,9};
static char d10_off[2]={0,10};

//设置光照阈值
int set_Lux_alarmnumber(int lux){
	L_alarm = lux; // 设置光照阈值
	return 0; // 返回0表示成功
}

//设置温度阈值
int set_Temperature_alarmnumber(int temp) {
	T_alarm = temp; // 设置温度阈值
	return 0; // 返回0表示成功
}

// GY39传感器线程函数
void* gy39_thread(void* arg) {
    
    while (system_running) {
        // 读取GY39传感器数据
        // 打印传感器数据（调试用）
        pthread_mutex_lock(&sensor_mutex);
        GY39();
        pthread_mutex_unlock(&sensor_mutex);
        
        // 读取间隔（可根据需要调整）
        usleep(1000000); // 1秒
    }
    
    printf("GY39传感器线程已停止\n");
    return NULL;
}

// 蜂鸣器控制线程函数
void* beeper_thread(void* arg) {
    while (system_running) {
        pthread_mutex_lock(&hardware_mutex);
        // if (alarm_triggered) {
        if(T > T_alarm || L > L_alarm){
            if(alarm_triggered==1){
                beep_control(1); // 触发报警，开启蜂鸣器
            }         
        }
        // } 
        else {
            beep_control(0); // 关闭蜂鸣器
        }
        pthread_mutex_unlock(&hardware_mutex);
        
        // 检查频率，可根据需要调整
        usleep(10000); // 10ms
    }
    
    // 系统退出时确保蜂鸣器关闭
    beep_control(0);
    return NULL;
}

void* warning_thread(void* arg) {
    while (system_running) {
        pthread_mutex_lock(&hardware_mutex);
        if(T > T_alarm || L > L_alarm){
            print_warning_sign(48,216); // 显示警告标志
        }
        pthread_mutex_unlock(&hardware_mutex);
        usleep(100000); // 100ms
    }
    return NULL;
}

// LED控制线程函数
void* led_thread(void* arg) {
    while (system_running) {
        pthread_mutex_lock(&hardware_mutex);
        if (T > T_alarm || L > L_alarm) {
            led_flow_control(0); // 触发报警，LED闪烁
        } else {
            led_flow_control(1); // 正常状态LED
        }
        pthread_mutex_unlock(&hardware_mutex);
        
        // 检查频率，可根据需要调整
        usleep(200000); // 200ms
    }
    
    // 系统退出时确保LED处于安全状态
    led_flow_control(0); // 关闭所有LED
    return NULL;
}

void* handle_touch_event(void* arg) {
    int x, y;
    while (1) {
        get_user_input(&x, &y);
        if (x >= 0 && x <= 800 && y >= 0 && y <= 480) {
            stop_beep = 1;
            beep_control(0);
        }
        usleep(100000);
    }
    return NULL;
}

//获取触摸坐标
int get_user_input(int *x, int *y){
    touch_fd = open("/dev/input/event0", O_RDWR); // 打开触摸屏设备文件
    if (touch_fd < 0) {
        perror("open touch error");
        return -1;
    }
    struct input_event ev;
    int flag_x = 0;
    int flag_y = 0;
    while (1)
    {
        int res = read(touch_fd, &ev, sizeof(ev));
        if (res != sizeof(ev))
        {
            continue;
        }

        if (ev.type == EV_ABS && ev.code == ABS_X)
        {
            *x = ev.value * LCD_WIDTH / 1024; // Adjust scaling factor if needed
            flag_x = 1;
        }
        else if (ev.type == EV_ABS && ev.code == ABS_Y)
        {
            *y = ev.value * LCD_HEIGHT / 600; // Adjust scaling factor if needed
            flag_y = 1;
        }

        if (flag_x && flag_y)
        {
            break;
        }
    }
    return 0;
}

//led灯控制
int led_flow_control(int led_status){
    led_fd = open("/dev/led_drv",O_RDWR);
    if(led_fd < 0){
        perror("open led_drv error");
        return -1;
    }
    if(led_status == 0){
    	write(led_fd,d8_off,2);
        write(led_fd,d7_off,2);
        write(led_fd,d9_off,2);
        write(led_fd,d10_off,2);
        return 0;
    }
    if(led_status == 1){
        write(led_fd,d7_on,2);
        sleep(1);
    	write(led_fd,d7_off,2);
        write(led_fd,d8_on,2);
        sleep(1);
        write(led_fd,d8_off,2);
        write(led_fd,d9_on,2);
        sleep(1);
        write(led_fd,d9_off,2);
        write(led_fd,d10_on,2);
        sleep(1);
        write(led_fd,d10_off,2);
        return 0;
    }
    return -1;
}

//蜂鸣器控制
int beep_control(int beep_status){
    beep_fd = open(PWM_PATH,O_RDWR);
    if(beep_fd < 0){
        perror("open beep error");
        return -1;
    }
    
    if(beep_status == 0){
        char buf = 0;
    	int ret = write(beep_fd,&buf,1);
    	if(ret < 0){
    		perror("write beep error");
    		close(beep_fd);
    		return -1;
        }
    }
    if(beep_status == 1){
    	char buf = 1;
    	int ret = write(beep_fd,&buf,1);
    	if(ret < 0){
    		perror("write beep error");
    		close(beep_fd);
    		return -1;
        }
    }
    close(beep_fd);
    return 0;
}

// 拆分整数和小数部分（支持负数）
void split_decimal(int num, int* integer_part, int* decimal_part) {
    if (num < 0) {
        *integer_part = num / 10; // 整数部分（包含符号）
        *decimal_part = - (num % 10); // 小数部分取绝对值
    } else {
        *integer_part = num / 10;
        *decimal_part = num % 10;
    }
}

//在屏幕上画点
void LCD_draw_point(int x, int y, int color){
    
    if (x >= 0 && x < 800 && y >= 0 && y < 480)
    {
        *(plcd + 800 * y + x) = color;
    }
}

//显示字符
void display_char(int x0,int y0,int w,int h,unsigned char name[]){
    int x,y; //表示显示范围，字符显示的实际的行和列
    int i,j; //i，数组的第几个元素， j表示第几个bit位
    for(i = 0; i<w*h/8;i++){
    //对name[i]进行分析
        for(j = 0 ;j<8;j++){
            //对这里面的每个bit位进行分析，8个 一个一个分析
            if(name[i] &(1<<(7-j))) //考虑了大端小端的问题
            {
            //这个bit位应该要显示
                x = i/(w/8) + y0; //得到的字符的实际的行
                y = i%(w/8)*8 + j + x0; //得到的字符的实际的列
                LCD_draw_point(y,x,0x000000);
            }
        }
    }
}

void display_char_warning(int x0,int y0,int w,int h,unsigned char name[]){
	int x,y; //表示显示范围，字符显示的实际的行和列
    int i,j; //i，数组的第几个元素， j表示第几个bit位
    for(i = 0; i<w*h/8;i++){
    //对name[i]进行分析
        for(j = 0 ;j<8;j++){
            //对这里面的每个bit位进行分析，8个 一个一个分析
            if(name[i] &(1<<(7-j))) //考虑了大端小端的问题
            {
            //这个bit位应该要显示
                x = i/(w/8) + y0; //得到的字符的实际的行
                y = i%(w/8)*8 + j + x0; //得到的字符的实际的列
                LCD_draw_point(y,x,0xff0000);
            }
        }
    }
}

// 显示小数点（位置：x0+24*n，y0）
void display_decimal_point(int x0, int y0) {
    // 定义小数点的点阵（示例：简单实心点，需根据字体调整）
    //24*48
    unsigned char decimal_point[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x1F,0x80,0x00,0x3F,
        0xC0,0x00,0x3F,0xC0,0x00,0x1F,0x80,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    display_char(x0, y0, 24, 48, decimal_point); // 假设小数点宽度为24像素
}

int count_digits(int num) {
    if (num == 0) return 1;
    if (num == INT_MIN) return 10;  // 处理INT_MIN溢出问题
    num = (num < 0) ? -num : num;
    return (int)log10(num) + 1;
}

// 提取数字的每一位到数组（支持负数，返回位数）
int get_digits(int num, int* digits) {
    if (num == 0) {
        digits[0] = 0;
        return 1;
    }
    int index = 0;
    int is_negative = 0;
    if (num < 0) {
        if (num == INT_MIN) { // 处理INT_MIN溢出
            digits[index++] = -1; // 符号位用-1表示
            num = INT_MAX; // 剩余部分按正数处理
        } else {
            is_negative = 1;
            num = -num;
        }
    }
    // 分解数字
    while (num > 0) {
        digits[index++] = num % 10;
        num /= 10;
    }
    if (is_negative || (index == 0 && num == INT_MAX)) { // 处理符号位
        digits[index++] = -1;
    }
    // 反转数组，使高位在前
    for (int i = 0; i < index / 2; i++) {
        int temp = digits[i];
        digits[i] = digits[index - 1 - i];
        digits[index - 1 - i] = temp;
    }
    return index;
}

int uart_init(const char *uart_name){
    int fd = open(uart_name, O_RDWR | O_NOCTTY); // 关闭非阻塞模式（默认阻塞）
    if (fd == -1) {
        perror("uart open error!\n");
        return -1;
    }
    struct termios options;
    if (tcgetattr(fd, &options) != 0){
        perror("get serial config error!\n");
        close(fd);
        return -1;
    }
    // 设置波特率
    cfsetispeed(&options, GY39_BAUD_RATE);
    cfsetospeed(&options, GY39_BAUD_RATE);
    // 数据位：8位，无校验，1位停止位
    options.c_cflag &= ~PARENB;    // 无校验位
    options.c_cflag &= ~CSTOPB;    // 1位停止位
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;        // 8位数据位
    // 关闭流控制
    options.c_cflag &= ~CRTSCTS;
    // 设置为原始模式（不处理输入输出）
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_oflag &= ~OPOST;
    // 设置超时：最多等待1秒（10个0.1秒单位）
    options.c_cc[VMIN] = 0;        // 不阻塞，返回已接收的字节数（0或更多）
    options.c_cc[VTIME] = 10;
    if (tcsetattr(fd, TCSANOW, &options) != 0){
        perror("set serial config error!\n");
        close(fd);
        return -1;
    }
    tcflush(fd, TCIOFLUSH); // 清空输入缓冲区
    return fd;
}

int GY39() {
    int fd = uart_init(UART_PATH);
    if (fd == -1) {
        return -1;
    }

    int temperature = 0;    // 温度（单位：0.1℃）
    int pressure = 0;       // 气压（单位：0.1hPa）
    int altitude = 0;       // 海拔（单位：m）
    int humidity = 0;       // 湿度（单位：0.1%RH）
    int lux = 0;            // 光照强度（单位：lx）

    // 命令帧：光照强度（0xA5 0x81 0x26）
    const unsigned char light_cmd[3] = {0xA5, 0x81, 0x26};
    // 命令帧：温度/气压/海拔/湿度（0xA5 0x82 0x27）
    const unsigned char env_cmd[3] = {0xA5, 0x82, 0x27};

    unsigned char return_data_type2[9] = {0}; // 光照数据（9字节）
    unsigned char return_data_type1[15] = {0}; // 环境数据（15字节）
    int r = 0;

    
    while (1) {
        
        // -------------------- 读取光照强度 --------------------
        r = write(fd, light_cmd, sizeof(light_cmd));
        if (r != sizeof(light_cmd)) {
            printf("get r error: (r=%d)\n", r);
            usleep(200000); // 200ms后重试
            continue;
        }

        // 等待传感器响应（根据手册调整延时）
        usleep(200000); // 200ms
        memset(return_data_type2, 0, sizeof(return_data_type2));
        r = read(fd, return_data_type2, sizeof(return_data_type2));

        if (r == 9 && 
            return_data_type2[0] == 0x5A && 
            return_data_type2[1] == 0x5A && 
            return_data_type2[2] == 0x15) 
        {
            // 解析光照强度（16位，高字节在前，位于第4、5字节）
            uint16_t lux_raw = (return_data_type2[4] << 24 | return_data_type2[5] << 16 | return_data_type2[6] << 8 | return_data_type2[7]);
            lux = lux_raw / 100; // 
            L = lux;
            printf("lux: %d    L_alarm = %d", L,L_alarm);
            if(L > L_alarm){
            	printf("    Attention!!!\n");
            }
            else{
                printf("\n");
            }
            
        } else {
            printf("get lux error\n");
            continue; // 跳过本次循环，重新读取
        }

        // -------------------- 读取环境数据 --------------------
        r = write(fd, env_cmd, sizeof(env_cmd));
        if (r != sizeof(env_cmd)) {
            printf("set environment cmd error: (r=%d)\n", r);
            usleep(200000);
            continue;
        }

        usleep(200000); // 200ms
        memset(return_data_type1, 0, sizeof(return_data_type1));
        r = read(fd, return_data_type1, sizeof(return_data_type1));

        if (r == 15 && 
            return_data_type1[0] == 0x5A && 
            return_data_type1[1] == 0x5A && 
            return_data_type1[2] == 0x45) 
        {
            // 温度（第5、6字节，16位有符号数，单位：0.1℃）
            int16_t temp_raw = (return_data_type1[4] << 8) | return_data_type1[5];
            temperature = temp_raw / 10; // 例如：0x0123 -> 291 -> 29.1℃
            T = temperature;

            // 气压（第7-10字节，32位无符号数，单位：0.1hPa）
            uint32_t pre_raw = (return_data_type1[6] << 24) | 
                             (return_data_type1[7] << 16) | 
                             (return_data_type1[8] << 8) | 
                              return_data_type1[9];
            pressure = pre_raw / 1000; 
            P = pressure;

            // 湿度（第11、12字节，16位无符号数，单位：0.1%RH）
            uint16_t hum_raw = (return_data_type1[10] << 8) | return_data_type1[11];
            humidity = hum_raw / 10; // 例如：0x03E8 -> 1000 -> 100.0%RH
            H = humidity;

            // 海拔（第13、14字节，16位有符号数，单位：m）
            int16_t alt_raw = (return_data_type1[12] << 8) | return_data_type1[13];
            altitude = alt_raw; // 例如：0x0064 -> 100m
            A = altitude;

            // printf("temperuture: %d.%d`C  humality: %d.%d%%  pressure: %dhPa  atitude: %dm\n",
            //        temperature / 10, temperature % 10,
            //        humidity / 10, humidity % 10,
            //        pressure / 10, altitude);
            printf("T = %d    T_alarm = %d", T,T_alarm);
            if(T > T_alarm){
            	printf("    Attention!!!\n");
            }
            else{
                printf("\n");
            }
            
        } else {
            printf("environment verify error\n");
        }
        showdata_in_lcd();
        sleep(0.5); // 每秒读取一次
        
    }

    close(fd);
    return 0;
}

//lcd初始化
int lcd_init(){
    //1.打开屏幕文件
    lcd_fd = open(LCD_PATH,O_RDWR);//可读可写打开
    if(lcd_fd<0)
    {
        perror("open fail");
        return -1;
    }
    //2.映射 
    plcd = mmap(NULL, 
                800*480*4, 
                PROT_READ | PROT_WRITE, 
                MAP_SHARED,
                lcd_fd,
                0);
    if(plcd == MAP_FAILED)
    {
        perror("MAP fail");
        return -1;
    }
    return 0;
}

//LCD关闭
void lcd_close(){
    munmap(plcd,800*480*4);
    close(lcd_fd);
}

// 显示数字（支持负数，x0为起始列，y0为起始行，间距为字符宽度）
void display_number(int x0, int y0, int num) {
    int digits[12] = {0}; // 最多支持12位数字
    int len = get_digits(num, digits);
    for (int i = 0; i < len; i++) {
        int digit = digits[i];
        if (digit == -1) { // 符号位显示'-'（需自定义'-'的点阵，此处暂用空格代替）
            // 若需要显示负号，需添加'-'的点阵数据
            x0 += 24; // 预留符号位宽度（假设与数字同宽）
            continue;
        }
        display_char(x0, y0, 24, 48, numdz[digit]); // 24x48为字体宽高
        x0 += 24; // 字符间距为字体宽度
    }
}

//清屏函数，用来将从(x0,y0)为起点，宽w，高h的矩形区域显示为 color色
int lcd_draw_clear(int x0,int y0,int w,int h,int color){


	int x = 0;
	int y = 0;

	for(x=x0;x<=x0+w;x++)
	{
		for(y=y0;y<=y0+h;y++)
		{
			LCD_draw_point(x,y, color);
		}
	}

	return 0;
}

//显示图片
int show_bmp(char * filename,int x0,int y0){
    //1.打开bmp图片
    int fd = open("showdata_1.bmp",O_RDWR);
    //判断读入图片是否错误
    if (-1 == fd)
    {
        printf("Open %s Fail!\n",filename);
        perror("--->");
        return -1;
    }

    //2.判断到底是不是一张bmp图片
	unsigned char buf[4];
	read(fd,buf,2);
	if(buf[0]!= 0x42 || buf[1]!= 0x4d)//若果不是B M 的ASCII码
	{
		printf("NOT BMP\n");
		goto ERROR_END;
	}

    //3.读取数据
    
    int width,height;
    short depth;
	lseek(fd,0x12,SEEK_SET);
	read(fd,buf,4);
	
	width=(buf[3]<<24)|
		  (buf[2]<<16)|
		  (buf[1]<<8)|
		  (buf[0]);

	lseek(fd,0x16,SEEK_SET);
	read(fd,buf,4);
	
	height=(buf[3]<<24)|
		  (buf[2]<<16)|
		  (buf[1]<<8)|
		  (buf[0]);

	lseek(fd,0x1c,SEEK_SET);
	read(fd,buf,2);
	
	depth=(buf[1]<<8)|
		  (buf[0]);

	//只支持色深为24和32的
	if(!(depth == 24 || depth == 32))
	{
		printf("NOT Support!\n");
		goto ERROR_END;
	}
	// printf("%s:%d*%d depth=%d\n",filename,width,height,depth);

	//4.获取像素数组
	int line_valid_bytes = abs(width)*depth/8;//一行有效字节数
	int line_bytes;//一行总字节数=有效字节数+赖子数 
	int laizi = 0;
	
	if(line_valid_bytes%4)
	{
		laizi = 4-line_valid_bytes%4;
	}
	
	line_bytes = line_valid_bytes + laizi;
	
	int total_bytes = line_bytes*abs(height);//整个像素数组的大小


	//开辟一块动态内存
	unsigned char *piexl = (unsigned char *)malloc(total_bytes);    //用完后需要释放内存

	lseek(fd,54,SEEK_SET);
	read(fd,piexl,total_bytes);

    
	unsigned char a,r,g,b;
	int color;
	int i = 0;

	int x,y;
	for(y=0;y<abs(height);y++)
	{
		for(x=0;x<abs(width);x++)
		{
			//a r g b 0xargb 小端模式  b g r a
			b = piexl[i++];
			g = piexl[i++];
			r = piexl[i++];
			if(depth == 32)
			{
				a = piexl[i++];
			}
			else
			{
				a = 0;//不透明
			}
			color=(a<<24)|(r<<16)|(g<<8)|(b);

			//在屏幕对应的位置显示
			LCD_draw_point(width>0?x0+x:x0+abs(width)-x-1, 
							height>0?y0+abs(height)-y-1:y0+y,
							color);
		}
		//每一行的末尾 有可能填充几个赖子
		i += laizi;
	}

    //释放内存
    free(piexl);
    //关闭显示
	close(fd);
    ERROR_END:
		close(fd);
		return -2;
}

// 显示带小数的数字（如25.3，x0为起始列，y0为起始行）
void display_number_with_decimal(int x0, int y0, int num) {
    int integer_part, decimal_part;
    split_decimal(num, &integer_part, &decimal_part);
    
    // 显示整数部分
    display_number(x0, y0, integer_part);
    x0 += count_digits(integer_part) * 24; // 整数部分宽度
    
    // 显示小数点
    display_decimal_point(x0, y0);
    x0 += 24; // 小数点宽度
    
    // 显示小数部分
    display_number(x0, y0, decimal_part);
}

// 显示数据在LCD上
int showdata_in_lcd(){
    if (lcd_init() != 0) return -1;
    lcd_draw_clear(0, 0, 800, 480, 0xFFFFFF); // 白色背景
    show_bmp("showdata.bmp", 0, 0);
    // GY39();
    int x_pos = 300; // 水平起始位置
    int y_pos = 70; // 垂直起始位置
    while (1) {
        // sleep(1);
        // 显示温度（T为0.1℃单位，如253表示25.3℃）
        display_number_with_decimal(x_pos, y_pos, T);
        y_pos += 80; // 每行间隔50像素
        // 显示湿度（H为0.1%RH单位，如456表示45.6%）
        display_number_with_decimal(x_pos, y_pos, H);
        display_char(x_pos+26*4, y_pos, 24, 48, percentchar); // 显示百分号
        y_pos += 80;
        // 显示海拔（A为整数，无需小数）
        display_number(x_pos, y_pos, A);
        display_char(x_pos+26*2, y_pos, 48, 48, meterchar);
        y_pos += 80;
        // 显示气压（P为0.1hPa单位，如10132表示1013.2hPa）
        display_number_with_decimal(x_pos, y_pos, P);
        display_char(x_pos+26*6, y_pos, 48, 48, baichar);
        display_char(x_pos+26*6+50, y_pos, 48, 48, pachar);
        y_pos += 80;
        // 显示光照（L为整数，无需小数）
        display_number(x_pos, y_pos, L);
        y_pos = 70; // 重置垂直位置
        return 1;
    }
    lcd_close();
    return 0;
}

int print_warning_sign(int x,int y){
    display_char_warning(x, y, 48, 48, warning_sign);
    return 0;
}

int main(int argc, char *argv[]) {
    // display_char(500,100,48,48,warning_sign);
    //设置阈值
    set_Temperature_alarmnumber(300);
    set_Lux_alarmnumber(200);

    pthread_t gy39_tid, beeper_tid, led_tid, warning_tid;
    // 创建控制线程
    if (pthread_create(&gy39_tid, NULL, gy39_thread, NULL) != 0 ||
        pthread_create(&beeper_tid, NULL, beeper_thread, NULL) != 0 ||
        pthread_create(&led_tid, NULL, led_thread, NULL) != 0 ||
        pthread_create(&warning_tid, NULL, warning_thread, NULL) != 0 ){
        perror("线程创建失败");
        return 1;
    }
    
    // 主循环（根据GY39数据控制报警）
    while (system_running) {
        int x, y;
        get_user_input(&x, &y); // 获取触摸坐标
        printf("Touch detected at (%d, %d)\n", x, y);



        //触摸后重置报警状态
        pthread_mutex_lock(&hardware_mutex);
        alarm_triggered = !alarm_triggered;
        printf("alarm_triggered = %d\n", alarm_triggered);
        pthread_mutex_unlock(&hardware_mutex);

        // 主循环休眠
        usleep(50000); // 50ms
    }
    
    //等待线程结束
    pthread_join(gy39_tid, NULL);
    pthread_join(beeper_tid, NULL);
    pthread_join(led_tid, NULL);
    pthread_join(warning_tid, NULL);
    
    

    return 0;
}